package me.eachann.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.os.Build;
import android.text.Editable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;

/**
 * 带清空按钮的文本输入组件
 */
public class ClearEditText extends RelativeLayout {
    private EditText mEditText;
    private TextView mPrefix;
    private ArrayList<TextWatcher> mListeners = new ArrayList<>();

    public ClearEditText(Context context) {
        this(context, null);
    }

    public ClearEditText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ClearEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initGlobalView(context);
        initAttrs(context, attrs, defStyleAttr);
    }

    private void initAttrs(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.ClearEditText, defStyleAttr, 0);
        try {
            mEditText.setText(a.getString(R.styleable.ClearEditText_text));
            setInputType(a.getInt(R.styleable.ClearEditText_inputType, 0));
            setHint(a.getString(R.styleable.ClearEditText_hint));
            if (TextUtils.isEmpty(a.getString(R.styleable.ClearEditText_editPrefix))) {
                mEditText.setPadding(0, getDPSize(R.dimen.clear_edit_text_dimen_8dp), getDPSize(R.dimen.clear_edit_text_dimen_32dp), getDPSize(R.dimen.clear_edit_text_dimen_8dp));
            } else {
                mPrefix.setText(a.getString(R.styleable.ClearEditText_editPrefix));
                mEditText.setPadding(getDPSize(R.dimen.clear_edit_text_dimen_68dp), getDPSize(R.dimen.clear_edit_text_dimen_8dp), getDPSize(R.dimen.clear_edit_text_dimen_32dp), getDPSize(R.dimen.clear_edit_text_dimen_8dp));
            }
            setMaxLength(a.getInt(R.styleable.ClearEditText_maxLength, -1));
        } finally {
            a.recycle();
        }
    }

    private void initGlobalView(Context context) {
        ViewGroup.LayoutParams rootParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        setLayoutParams(rootParams);
        mEditText = (EditText) LayoutInflater.from(context).inflate(R.layout.clear_edit_text_layout, null, false);
        LayoutParams editTextParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        editTextParams.addRule(CENTER_IN_PARENT, RelativeLayout.TRUE);
        mEditText.setBackgroundResource(R.drawable.drawable_edit_text_bottom_line);
        mEditText.setSingleLine(true);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            mEditText.setTextCursorDrawable(R.drawable.drawable_edit_text_cursor);
        } else {
            try {
                // https://github.com/android/platform_frameworks_base/blob/kitkat-release/core/java/android/widget/TextView.java#L562-564
                Field f = TextView.class.getDeclaredField("mCursorDrawableRes");
                f.setAccessible(true);
                f.set(mEditText, R.drawable.drawable_edit_text_cursor);
            } catch (Exception ignored) {
            }
        }
        mEditText.setMinimumHeight(getDPSize(R.dimen.clear_edit_text_dimen_32dp));
        mEditText.setHintTextColor(Color.parseColor("#999999"));
        mEditText.setTextSize(15);
        mEditText.setTextColor(Color.parseColor("#333333"));
//        mEditText.setPadding(getDPSize(R.dimen.clear_edit_text_dimen_68dp), getDPSize(R.dimen.clear_edit_text_dimen_8dp), getDPSize(R.dimen.clear_edit_text_dimen_32dp), getDPSize(R.dimen.clear_edit_text_dimen_8dp));
        addView(mEditText, editTextParams);
        LayoutParams prefixParams = new LayoutParams(getDPSize(R.dimen.clear_edit_text_dimen_60dp), ViewGroup.LayoutParams.WRAP_CONTENT);
        prefixParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
        prefixParams.addRule(RelativeLayout.ALIGN_PARENT_START, RelativeLayout.TRUE);
        mPrefix = new TextView(context);
        mPrefix.setTextSize(15);
        mPrefix.setTextColor(Color.parseColor("#333333"));
        addView(mPrefix, prefixParams);
        RelativeLayout.LayoutParams delContainerParams = new RelativeLayout.LayoutParams(getDPSize(R.dimen.clear_edit_text_dimen_32dp), mEditText.getMinimumHeight());
        View delContainerView = new View(context);
        delContainerParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
        delContainerParams.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE);
        delContainerView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mEditText.setText(null);
            }
        });
        addView(delContainerView, delContainerParams);

        RelativeLayout.LayoutParams delParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        delParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
        delParams.addRule(RelativeLayout.ALIGN_PARENT_END, RelativeLayout.TRUE);
        final ImageView ivDel = new ImageView(context);
        ivDel.setImageResource(R.drawable.ic_clear_edit_text);
        ivDel.setVisibility(INVISIBLE);
        addView(ivDel, delParams);
        TextWatcher watcher = new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                ivDel.setVisibility(s.length() > 0 ? VISIBLE : INVISIBLE);
            }
        };
        mListeners.add(watcher);
        mEditText.addTextChangedListener(watcher);
    }

    //过滤空格
    InputFilter mBlankFilter = new InputFilter() {
        @Override
        public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
            if (source.equals(" ")) {
                return "";
            } else {
                return null;
            }
        }
    };

    /**
     * getDimensionPixelSize
     *
     * @param p DimenRes
     * @return px unit size
     */
    private int getDPSize(int p) {
        return getContext().getResources().getDimensionPixelSize(p);
    }

    public final void setText(int resid) {
        mEditText.setText(resid);
    }

    public final void setText(CharSequence text) {
        mEditText.setText(text);
    }

    public final void setMaxLength(int max) {
        if (max >= 0) {
            mEditText.setFilters(new InputFilter[]{mBlankFilter, new InputFilter.LengthFilter(max)});
        } else {
            mEditText.setFilters(new InputFilter[]{mBlankFilter});
        }
    }

    public final CharSequence getText() {
        return mEditText.getText();
    }

    public final void setHintTextColor(int color) {
        mEditText.setHintTextColor(color);
    }

    public final void setHint(int resid) {
        mEditText.setHint(resid);
    }

    public final void setHint(CharSequence text) {
        mEditText.setHint(text);
    }

    public void setSelection(int index) {
        mEditText.setSelection(index);
    }

    /**
     * 设置选中文本末尾
     */
    public void setSelectionEnd() {
        setSelection(mEditText.getText().length());
    }

    private int dp2px(float dp) {
        return (int) (dp * getContext().getResources().getDisplayMetrics().density + 0.5f);
    }

    public void addTextChangedListener(TextWatcher watcher) {
        if (mListeners == null) {
            mListeners = new ArrayList<>();
        }
        mListeners.add(watcher);
        mEditText.addTextChangedListener(watcher);
    }

    public void setInputType(int type) {
        switch (type) {
            case 0:
                mEditText.setInputType(InputType.TYPE_CLASS_TEXT);
                break;
            case 1:
                mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_NORMAL);
                break;
            case 2:
                mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
                break;
            case 3:
                mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
                break;
            case 4:
                mEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
                break;
            case 5:
                mEditText.setInputType(InputType.TYPE_CLASS_PHONE);
                break;
            case 6:
//                <!-- Text that will be used as an e-mail address.  Corresponds to
//            {@link android.text.InputType#TYPE_CLASS_TEXT} |
//            {@link android.text.InputType#TYPE_TEXT_VARIATION_EMAIL_ADDRESS}. -->
                mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
                break;
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        for (TextWatcher w : mListeners) {
            mEditText.removeTextChangedListener(w);
        }
        super.onDetachedFromWindow();
    }
}
